#include <hw/i2c.h>
#include <malloc.h>
#include <devctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#include "set_max2008x_power.h"

I2C_Config_st i2c_dev;

int max9286_power(int channel_num, int state_){

//	int i2c_fd = -1;
	i2c_dev.i2c_fd = I2C_Open(PATH_I2C);
	I2C_Config(&i2c_dev, i2c_dev.i2c_fd, max2008x_pulldown_addr, 7);
	I2C_SetSpeed(&i2c_dev, i2c_speed);

	uint8_t dat = 0;
	uint8_t cmd_date = 0x01;
	
	I2C_Read(i2c_dev, &cmd_date, 1,&dat, 1);
	printf("max2008x config state dat:%d \n", dat);

	dat =dat & (~channel_num);

	if(state_){
		dat = dat | channel_num;
//		printf("set max9286_power -%d- state:ON \n",channel_num);
	}

	I2C_Write(i2c_dev, &cmd_date, 1,&dat, 1);

	I2C_Close(i2c_dev.i2c_fd);
	return 0;
}

int max96706_power(int channel_num, int state_){
	i2c_dev.i2c_fd = I2C_Open(PATH_I2C);
	I2C_Config(&i2c_dev, i2c_dev.i2c_fd, max2008x_pullup_addr, 7);
	I2C_SetSpeed(&i2c_dev, i2c_speed);

	uint8_t dat = 0;
	uint8_t cmd_date = 0x01;

	I2C_Read(i2c_dev, &cmd_date, 1,&dat, 1);
	printf("max2008x config state dat:%d \n", dat);

	if(state_){
		dat = (dat & 0xf0) | channel_num;
		printf("set max96706_power -%d- state:ON \n",channel_num);
	}else{
		dat = (dat & 0xf0) & (~channel_num);   // &(~(0x01 << 7))
		printf("set max96706_power -%d- state:OFF \n",channel_num);
	}

	I2C_Write(i2c_dev, &cmd_date, 1,&dat, 1);

	I2C_Close(i2c_dev.i2c_fd);
	return 0;
}

int I2C_Open(const char* i2c_addr)
{
	int i2c_fd = -1;

	i2c_fd = open(i2c_addr, O_RDWR);

	return i2c_fd;
}

int I2C_Config(I2C_Config_st* i2c_dev,int i2c_fd,int slaveaddr,int slaveaddr_fmt)
{
	i2c_dev->i2c_fd = i2c_fd;
	i2c_dev->slaveaddr = slaveaddr;
	i2c_dev->stop_bytes = 1;

	if(slaveaddr_fmt == 7)
	{
		i2c_dev->slaveaddr_fmt = I2C_ADDRFMT_7BIT;
	}
	else if(slaveaddr_fmt == 10)
	{
		i2c_dev->slaveaddr_fmt = I2C_ADDRFMT_10BIT;
	}
	else
	{
		i2c_dev->slaveaddr_fmt = I2C_ADDRFMT_7BIT;
	}

	return 0;
}


int I2C_Write(I2C_Config_st i2c_dev,uint8_t* cmd,int cmd_len,uint8_t* dat,int dat_len)
{
	struct sndmsg_st{
		i2c_send_t hdr;
		uint8_t	   snd_dat[0];
	};

	int ret=-1;
	int rtnum=0;
	struct sndmsg_st* pMsg;
	int len= sizeof(struct sndmsg_st);
	int send_len=0;

	send_len = cmd_len + dat_len;

	pMsg = (struct sndmsg_st*)malloc(len+send_len);
	if(pMsg == NULL)
	{
		return -1;
	}

	memset(pMsg,0,len+send_len);

	pMsg->hdr.slave.addr = i2c_dev.slaveaddr;
	pMsg->hdr.slave.fmt = i2c_dev.slaveaddr_fmt;
	pMsg->hdr.len = send_len;
	pMsg->hdr.stop = i2c_dev.stop_bytes;

	memcpy(pMsg->snd_dat,cmd,cmd_len);

	if(dat_len != 0)
		memcpy(&pMsg->snd_dat[cmd_len],dat,dat_len);

	//fprintf(stderr,"%s cmd[0]=%x cmd[1]=%x data=%x\n",__FUNCTION__,pMsg->snd_dat[0],pMsg->snd_dat[1],dat[0]);

	ret = devctl(i2c_dev.i2c_fd, DCMD_I2C_SEND, pMsg, len+send_len, &rtnum);

	if(pMsg != NULL)
		free(pMsg);

	return (ret);
}

int I2C_Read(I2C_Config_st i2c_dev,uint8_t* cmd,int cmd_len,uint8_t* dat,int dat_len)
{
	struct sndmsg_st{
		i2c_send_t hdr;
		uint8_t	   snd_dat[0];
	};
	struct rcvmsg_st{
		i2c_recv_t hdr;
		uint8_t	   rcv_dat[0];
	};

	int len= 0;
	int rbytes;
	struct sndmsg_st* pSndMsg=NULL;
	struct rcvmsg_st* pRcvMsg=NULL;

	//send start
	len= sizeof(struct sndmsg_st);
	pSndMsg = (struct sndmsg_st*)malloc(len+cmd_len);
	if(pSndMsg == NULL)
	{
		return -1;
	}

	memset(pSndMsg,0,len+cmd_len);

	pSndMsg->hdr.slave.addr = i2c_dev.slaveaddr;
	pSndMsg->hdr.slave.fmt = i2c_dev.slaveaddr_fmt;
	pSndMsg->hdr.len = cmd_len;
	//pSndMsg->hdr.stop = i2c_dev.stop_bytes;
	pSndMsg->hdr.stop = 0;
	memcpy(pSndMsg->snd_dat,cmd,cmd_len);

	printf("%s cmd[0]=%x cmd[1]=%x \n",__FUNCTION__,pSndMsg->snd_dat[0],pSndMsg->snd_dat[1]);

	if(devctl(i2c_dev.i2c_fd, DCMD_I2C_SEND, pSndMsg, len+cmd_len, NULL))
	{
		if(pSndMsg != NULL)
			free(pSndMsg);
		return -1;
	}

	if(pSndMsg != NULL)
		free(pSndMsg);
	//send end

	//recv start
	len= sizeof(struct rcvmsg_st);
	pRcvMsg = (struct rcvmsg_st*)malloc(len+dat_len);
	if(pRcvMsg == NULL)
	{
		return -1;
	}

	memset(pRcvMsg,0,len+dat_len);

	pRcvMsg->hdr.slave.addr = i2c_dev.slaveaddr;
	pRcvMsg->hdr.slave.fmt = i2c_dev.slaveaddr_fmt;
	pRcvMsg->hdr.len = dat_len;
	pRcvMsg->hdr.stop = i2c_dev.stop_bytes;

	if (devctl(i2c_dev.i2c_fd, DCMD_I2C_RECV, pRcvMsg, len+dat_len,&rbytes))
	{
		if(pRcvMsg != NULL)
			free(pRcvMsg);

		return (-1);
	}

	if(rbytes <= dat_len)
	{
		memcpy(dat,pRcvMsg->rcv_dat,rbytes);
	}
	else
	{
		memcpy(dat,pRcvMsg->rcv_dat,dat_len);
	}

	if(pRcvMsg != NULL)
		free(pRcvMsg);

	return (0);
}
int I2C_SetSpeed(I2C_Config_st* i2c_dev,unsigned int speed)
{
	int ret=0;

	ret = devctl(i2c_dev->i2c_fd, DCMD_I2C_SET_BUS_SPEED, &speed, sizeof(unsigned int), NULL);
	if (ret != 0) {
		return -1;
	}
	else{
		i2c_dev->speed = speed;
	}

	return 0;
}

int I2C_Close(int i2c_fd)
{
	close(i2c_fd);

	return 0;
}

